有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

swing Java编译有没有办法告诉编译器忽略部分代码?

我维护一个JavaSwing应用程序

为了向后兼容Java5(对于Apple机器),我们维护了两个代码库,一个使用Java6的特性,另一个没有这些特性

除了使用Java6特性的3-4类之外,代码基本相同

我希望只维护1个代码库。在编译过程中,有没有办法让Java5编译器“忽略”我代码的某些部分

根据java编译器的版本,我不希望简单地注释/取消注释部分代码


共 (6) 个答案

  1. # 1 楼答案

    您可能可以重构代码,这样就不需要条件编译,只需要条件类加载。大概是这样的:

    public interface Opener{
    
    public void open(File f);
    
     public static class Util{
            public Opener getOpener(){
              if(System.getProperty("java.version").beginsWith("1.5")){
               return new Java5Opener();
              }
              try{ 
                return new Java6Opener();
               }catch(Throwable t){
                return new Java5Opener();
               }
            }
     }
    
    }
    

    这可能需要很大的努力,这取决于您有多少版本特定的代码

  2. # 2 楼答案

    我认为这里最好的方法可能是使用构建脚本。您可以将所有代码放在一个位置,通过选择要包含和不包含的文件,您可以选择要编译的代码版本。请注意,如果您需要比每个文件更细粒度的控制,这可能没有帮助

  3. # 3 楼答案

    关于使用自定义类加载器和动态注释代码的建议,在涉及到维护和维护在您重新开始新的项目后,无论哪个可怜的灵魂接手该项目,都有点令人难以置信

    解决办法很简单。将受影响的类拖出到两个独立的项目中——确保包名相同,然后编译成JAR,然后在主项目中使用。如果保持包名相同,方法签名相同,那么没有问题——只需将所需的jar版本放到部署脚本中即可。我假设您运行不同的构建脚本,或者在同一个脚本中有不同的目标—ant和maven都可以轻松地处理有条件地获取和复制文件

  4. # 4 楼答案

    保留一个在JDK5下构建的“主”源根目录。添加第二个必须在JDK 6或更高版本下构建的并行源根。(不应存在重叠,即两者中均不存在类。)使用一个接口来定义两者之间的入口点,以及一点点反射

    例如:

    ---%<--- main/RandomClass.java
    // ...
    if (...is JDK 6+...) {
        try {
            JDK6Interface i = (JDK6Interface)
                Class.forName("JDK6Impl").newInstance();
            i.browseDesktop(...);
        } catch (Exception x) {
            // fall back...
        }
    }
    ---%<--- main/JDK6Interface.java
    public interface JDK6Interface {
        void browseDesktop(URI uri);
    }
    ---%<--- jdk6/JDK6Impl.java
    public class JDK6Impl implements JDK6Interface {
        public void browseDesktop(URI uri) {
            java.awt.Desktop.getDesktop().browse(uri);
        }
    }
    ---%<---
    

    您可以在IDE中使用不同的JDK等将它们配置为单独的项目。重点是主根目录可以独立编译,并且非常清楚您可以在哪个根目录中使用什么,然而,如果您试图单独编译单个根目录的不同部分,那么很容易意外地将JDK 6的使用“泄漏”到错误的文件中

    而不是使用类。对于这样的名称,您还可以使用某种服务注册系统—java。util。ServiceLoader(如果main可以使用JDK 6,并且您想要对JDK 7的可选支持!),NetBeans查找、Spring等

    同样的技术也可以用于创建对可选库的支持,而不是对更新的JDK的支持

  5. # 5 楼答案

    假设这些类具有类似的功能,在实现上有1.5和6.0的不同,您可以将它们合并到一个类中。然后,无需编辑源代码以进行注释/取消注释,您就可以依靠编译器经常进行的优化。如果If表达式始终为false,则If语句中的代码将不包括在编译中

    您可以在一个类中创建一个静态变量,以确定要运行的版本:

    public static final boolean COMPILED_IN_JAVA_6 = false;
    

    然后让受影响的类检查该静态变量,并将代码的不同部分放入一个简单的if语句中

    if (VersionUtil.COMPILED_IN_JAVA_6) {
      // Java 6 stuff goes here
    } else {
      // Java 1.5 stuff goes here
    }
    

    然后,当您想要编译另一个版本时,您只需更改该变量并重新编译。它可能会使java文件变大,但它会整合您的代码并消除所有代码重复。您的编辑器可能会抱怨无法访问的代码或其他问题,但编译器应该很高兴地忽略它

  6. # 6 楼答案

    不是真的,但有一些变通办法。看见 http://forums.sun.com/thread.jspa?threadID=154106&messageID=447625

    也就是说,您应该坚持至少有一个Java5文件版本和一个Java6文件版本,并根据需要通过构建或制作来包含它们。将所有内容都放在一个大文件中,并试图让编译器忽略它不理解的内容,这不是一个好的解决方案

    --尼基--